package cn.iocoder.yudao.module.design.service.flow;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.security.core.LoginUser;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.design.controller.admin.flow.vo.*;
import cn.iocoder.yudao.module.design.controller.admin.house.vo.HouseRespVO;
import cn.iocoder.yudao.module.design.convert.flow.FlowConvert;
import cn.iocoder.yudao.module.design.dal.dataobject.flow.FlowCountDO;
import cn.iocoder.yudao.module.design.dal.dataobject.flow.FlowDO;
import cn.iocoder.yudao.module.design.dal.dataobject.flowmd.FlowMdDO;
import cn.iocoder.yudao.module.design.dal.dataobject.houseUserRel.HouseUserRelDO;
import cn.iocoder.yudao.module.design.dal.dataobject.node.NodeDO;
import cn.iocoder.yudao.module.design.dal.dataobject.userflowrel.UserFlowRelDO;
import cn.iocoder.yudao.module.design.dal.mysql.flow.FlowMapper;
import cn.iocoder.yudao.module.design.dal.mysql.flowmd.FlowMdMapper;
import cn.iocoder.yudao.module.design.dal.mysql.houseUserRel.HouseUserRelMapper;
import cn.iocoder.yudao.module.design.dal.mysql.node.NodeMapper;
import cn.iocoder.yudao.module.design.dal.mysql.purchase.PurchaseMapper;
import cn.iocoder.yudao.module.design.dal.mysql.userflowrel.UserFlowRelMapper;
import cn.iocoder.yudao.module.design.service.house.HouseService;
import cn.iocoder.yudao.module.design.service.node.NodeService;
import cn.iocoder.yudao.module.design.service.pic.PicService;
import cn.iocoder.yudao.module.design.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.design.enums.design.FlowCdEnum;
import cn.iocoder.yudao.module.design.enums.design.FlowStatusEnum;
import cn.iocoder.yudao.module.design.enums.design.UserRelStatusCdEnum;
import cn.iocoder.yudao.module.design.enums.user.DesignUserRoleEnum;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.design.enums.ErrorCodeConstants.FLOW_NOT_EXISTS;

/**
 * 流程信息 Service 实现类
 *
 * @author czw
 */
@Service
@Validated
@Slf4j
@Lazy
public class FlowServiceImpl implements FlowService {
    @Resource
    @Lazy
    private HouseService houseService;
    @Resource
    @Lazy
    private NodeService nodeService;

    @Resource
    private PicService picService;
    @Resource
    private FlowMdMapper flowMdMapper;
    @Resource
    private FlowMapper flowMapper;

    @Resource
    private PurchaseMapper purchaseService;
    @Resource
    private NodeMapper nodeMapper;

    @Resource
    private HouseUserRelMapper houseUserRelMapper;


    @Resource
    private UserFlowRelMapper userFlowRelMapper;
    @Resource
    private AdminUserService adminUserService;

    @Override
    public Long createFlow(FlowCreateReqVO createReqVO) {
        // 插入
        FlowDO flow = FlowConvert.INSTANCE.convert(createReqVO);
        flow.setDeleted(false);
        flowMapper.insert(flow);
        // 返回
        return flow.getId();
    }

    @Override
    public void updateFlow(FlowUpdateReqVO updateReqVO) {
        // 校验存在
        this.validateFlowExists(updateReqVO.getId());
        // 更新
        FlowDO updateObj = FlowConvert.INSTANCE.convert(updateReqVO);
        flowMapper.updateById(updateObj);

    }

    @Override
    public void deleteFlow(Long id) {
        // 校验存在
        this.validateFlowExists(id);
        // 删除
        int i = flowMapper.deleteById(id);
        if (i > 0) {
            QueryWrapper queryWrapper = new QueryWrapper();
            queryWrapper.eq("flow_id", id);
            nodeMapper.delete(queryWrapper);
        }

    }

    public  void validateFlowExists(Long id) {
        if (flowMapper.selectById(id) == null) {
            throw exception(FLOW_NOT_EXISTS);
        }
    }

    @Override
    public FlowDO getFlow(Long id) {
        return flowMapper.selectById(id);
    }

    @Override
    public List<FlowDO> getFlowList(Collection<Long> ids) {
        return flowMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<FlowDO> getFlowPage(FlowPageReqVO pageReqVO) {
        return flowMapper.selectPage(pageReqVO);
    }

    @Override
    public List<FlowDO> getFlowList(FlowExportReqVO exportReqVO) {
        return flowMapper.selectList(exportReqVO);
    }

    @Override
    public List<FlowDO> getFlowAll(FlowBaseVO flowBaseVO) {
        //  SecurityFrameworkUtils  getLoginUserRoleIds 获取当前用户角色 getLoginUser  获取当前用户  getLoginUserId  用户编号
        /*1.根据用户Id 获取角色Id   2. 根据角色查询不同的流程*/
        LoginUser loginUser = SecurityFrameworkUtils.getLoginUser();
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("house_id", flowBaseVO.getHouseId());
        Set<String> flowCds = new HashSet<>();

        flowCds.add("0");
//        flowCds.add("1");
        flowCds.add("2");
        queryWrapper.in("flow_cd", flowCds);// 施工流程
        return flowMapper.selectList(queryWrapper);
    }

    @Override
    public List<FlowDO> getFlowByStatus(Integer status) {
        return flowMapper.selectListByStatus(status);
    }

    /**
     * 新建采购流程
     *
     * @param baseVO
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createPurchaseFlow(FlowCreatePurcharseReqVO baseVO) {

        String nodeName = DateUtil.format(new Date(), "yyyyMMdd") + "-采购任务";
        String remark = "";

        // 查询项目信息
        HouseRespVO house = houseService.getHouseById(baseVO.getHouseId());
        // 查询采购流程信息
        QueryWrapper<FlowDO> queryFlowWrap = new QueryWrapper<FlowDO>();
        queryFlowWrap.eq("house_id", baseVO.getHouseId());
        // 采购流程
//        queryFlowWrap.eq("flow_cd","1");
//        FlowDO flowDO = flowMapper.selectOne(queryFlowWrap);
        // 新建采购流程
        FlowDO procurementFlow = new FlowDO();
        procurementFlow.setFlowName(nodeName);
        procurementFlow.setHouseId(baseVO.getHouseId());
        procurementFlow.setIsMainCd("0");
        procurementFlow.setStatusCd(FlowStatusEnum.FLOW_STATUS_ENUM_1.getCode());
        procurementFlow.setFlowCd(FlowCdEnum.FLOW_CD_1.getCode());
        procurementFlow.setDesignerId(house.getDesignerId());
        procurementFlow.setDeleted(false);
        procurementFlow.setCreator(SecurityFrameworkUtils.getLoginUserId().toString());
        procurementFlow.setRemark(remark);
         procurementFlow.setStartTime(baseVO.getStartTime());
        int count1 = flowMapper.insert(procurementFlow);
        if (count1 <= 0) {
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.IMPORT_PURCH_FLOW_ERROR);
        }else{
            // 保存供应商 和采购流程的关联关系
            saveHouseUserFlowRel(baseVO.getHouseId(),procurementFlow.getId(),baseVO.getSupplierId(),DesignUserRoleEnum.SUPPLIER.getRoleId());
            // 保存业主和采购流程关系
            saveHouseUserFlowRel(baseVO.getHouseId(),procurementFlow.getId(),house.getOwnerId(),DesignUserRoleEnum.OWNER.getRoleId());
            // 保存设计师和采购流程关系
            saveHouseUserFlowRel(baseVO.getHouseId(),procurementFlow.getId(),house.getDesignerId(),DesignUserRoleEnum.DESIGN.getRoleId());

            // 保存

        }

        // 关联采购清单
//        if (!purchaseList.isEmpty()) {
//            final AdminUserDO suppliser = adminUserService.getUser(baseVO.getSupplierId());
//            for (PurchaseCreateReqVO purchasevo : purchaseList
//            ) {
//                PurchaseDO purchase = new PurchaseDO();
//                purchase.setHouseId(procurementFlow.getHouseId());
//                purchase.setFlowId(procurementFlow.getId());
//                purchase.setPersonName(suppliser.getNickname());
//                purchase.setMobile(suppliser.getMobile());
//                purchase.setName(purchasevo.getName());
//                purchase.setCnt(purchasevo.getCnt());
//                purchase.setSize(purchasevo.getSize());
//                purchase.setPlace(purchasevo.getPlace());
//                purchase.setIsInstall(purchasevo.getIsInstall());
//                purchase.setStatusCd("0");//0-备货中   1-运输中  2-安装中  3-验收完成
//                purchase.setDeleted(false);
//
//                purchaseService.insert(purchase);
//                //10 附件 11合同  12图纸 13材料清单 14家电清单
//                // 保存图片
//                PicDO picDo = new PicDO();
//                picDo.setHouseId(procurementFlow.getHouseId());
//                picDo.setFlowId(procurementFlow.getId());
//                picDo.setItemId(purchase.getId());
//                picDo.setUploadType("0");
//                picDo.setSourceType("10");
//                // 保存附件
//                picService.savePicData(picDo,purchasevo.getFileList());
//                // 保存合同
//                picDo.setSourceType("11");
//                picService.savePicData(picDo,purchasevo.getContractFile());
//                // 保存图纸
//                picDo.setSourceType("12");
//                picService.savePicData(picDo,purchasevo.getDrawList());
//                // 保存清单清单
//                picDo.setSourceType("13");
//                picService.savePicData(picDo,purchasevo.getPurchaseList());
//            }
//        }
        // 查询采购流程模板
        QueryWrapper<FlowMdDO> queryFlowMdWrap = new QueryWrapper<FlowMdDO>();
        queryFlowMdWrap.eq("flow_cd", "1");
        queryFlowMdWrap.eq("id", "4");
        FlowMdDO flowMdDO = flowMdMapper.selectOne(queryFlowMdWrap);
        // 获取子节点模板
        String nextIds = flowMdDO.getChildren();

        // 查询所有采购流程
        QueryWrapper<NodeDO> queryNodeWrap = new QueryWrapper<NodeDO>();
        queryNodeWrap.eq("pre_id", "0");
        queryNodeWrap.eq("flow_id", procurementFlow.getId());

        Long aLong = nodeMapper.selectCount(queryNodeWrap);

        // 获取sordId 初始值
        int index = Integer.valueOf(Math.toIntExact(aLong)) + 1;


        Long preId = 0L;

        NodeDO nodeDO = new NodeDO();
        nodeDO.setPreId(preId);
        nodeDO.setFlowId(procurementFlow.getId());
        nodeDO.setHouseId(procurementFlow.getHouseId());
        nodeDO.setSortId(String.valueOf(index));
        nodeDO.setDesignerId(procurementFlow.getDesignerId());
        nodeDO.setFlowDtlCd("0");
        nodeDO.setNodeName(nodeName);
        nodeDO.setDealerId(baseVO.getDealerId());
        // 待开始
        nodeDO.setStartTime(baseVO.getStartTime());

        nodeDO.setStatusCd("0");
        nodeDO.setRemark(baseVO.getRemark());
        nodeDO.setSortId(String.valueOf(index));
        nodeDO.setCreator(SecurityFrameworkUtils.getLoginUserId().toString());
        nodeDO.setDeleted(false);
        nodeDO.setDealerId(baseVO.getSupplierId());
        nodeMapper.insert(nodeDO);

        preId = nodeDO.getId();
        index++;
        // 保存子节点信息
        if (StrUtil.isNotEmpty(nextIds)) {
            houseService.saveNextIdsData(procurementFlow.getId(), procurementFlow.getHouseId(), preId, procurementFlow.getDesignerId(), "0", nextIds);
        }

        // 发起采购任务待办
//        nodeService.createFlowTask(procurementFlow);
    }

    /**
     * @param houseId
     * @return
     */
    @Override
    public List<Map> getPurchaseFlow(Long houseId) {
        // 判断当前登录人是否为 项目内关联人
        final Long loginUserId = SecurityFrameworkUtils.getLoginUserId();

        // 先判断当前操作人是否是项目的关联人(状态正常)  不是 报错
        QueryWrapper<HouseUserRelDO> queryUserRel = new QueryWrapper<>();
        queryUserRel.eq("user_id",loginUserId);
        queryUserRel.eq("status", UserRelStatusCdEnum.USER_REL_STATUS_CD_1.getCode());
        queryUserRel.eq("house_id",houseId);
        final Long aLong = houseUserRelMapper.selectCount(queryUserRel);
        if(aLong<=0){
            throw ServiceExceptionUtil.exception(ErrorCodeConstants.NO_AUTHORITY_OPTION_BY_PROJECT);
        }
        //判断角色  不是则报错
//        final Set<Long> roleIds = SecurityFrameworkUtils.getLoginUserRoleIds();
        // 判断当前登录人角色  1.供应商  项目负责人 查自己的 2.设计师 业主 项目经理 材料  客服查全部的
        QueryWrapper flowWrapper = new QueryWrapper();
        // 供应商
        List<Map> flowListByCondition = new ArrayList<>();
//        if(roleIds.contains(DesignUserRoleEnum.SUPER_ADMIN.getRoleId())){
//            flowListByCondition = flowMapper.getFlowListByConditionAdmin(houseId, "1" );
//        }else{
//            final Object[] objects = roleIds.toArray();
            flowListByCondition = flowMapper.getFlowListByCondition(houseId, "1", loginUserId,null);
//        }

//        for (Map purchase: flowListByCondition   ) {
//            final Long id = (Long) purchase.get("id");
//            PicDO picDO = new PicDO();
//            Long houseId1 = (Long) purchase.get("houseId");
//            Long flowId2 = (Long) purchase.get("flowId")getPurchaseFlowList;
//
//            picDO.setHouseId(houseId1);
//            picDO.setFlowId(flowId2);
//            picDO.setItemId(id);
//
//            picDO.setUploadType("0");
//            picDO.setStatus("0");
//            List<PicDO> picData = picService.getPicData(picDO);
//            // 查询当前item 所有附件
//            Map<String, List<PicDO>> collect = picData.stream()
//                    .collect(Collectors.groupingBy(item -> item.getSourceType()));
//
//            // 保存附件
//            purchase.put("fileList",collect.get("10"));
//            // 保存合同
//            purchase.put("contractFile",collect.get("11"));
//            // 保存图纸
//            purchase.put("drawList",collect.get("12"));
//            // 保存清单清单
//            purchase.put("purchaseList",collect.get("13"));
//        }
        return flowListByCondition;
    }


    /**
     * 保存人员流程关系数据
     */
    @Transactional(rollbackFor = Exception.class)
    public void saveHouseUserFlowRel(Long houseId ,Long flowId ,Long userId ,Long roleId){
        // 判断 house_id flow_id user_id role_id 是否存在 status = 0 则修改  不存在新增
        QueryWrapper  queryWrapper = new QueryWrapper();
        queryWrapper.eq("house_id",houseId);
        queryWrapper.eq("flow_id",flowId);
        queryWrapper.eq("user_id",userId);
        queryWrapper.eq("role_id",roleId);
        queryWrapper.in("status",0,1);
        Long aLong = userFlowRelMapper.selectCount(queryWrapper);
        if(aLong>0){
            log.info("已存在对应流程数据，无需新增");
            return ;
        }

        // 保存用户流程关系
        UserFlowRelDO userFlowRelDO     = new UserFlowRelDO();
        userFlowRelDO.setHouseId(houseId);
        userFlowRelDO.setFlowId(flowId);
        userFlowRelDO.setUserId(userId);
        userFlowRelDO.setRoleId(roleId);
        userFlowRelDO.setStatus("1");
        userFlowRelMapper.insert(userFlowRelDO);
    }

    @Override
    public List<FlowDO> getFlow(FlowBaseVO flowBaseVO) {

        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("house_id", flowBaseVO.getHouseId());
        // 施工流程
        queryWrapper.in("flow_cd", flowBaseVO.getFlowCd());
        return flowMapper.selectList(queryWrapper);
    }
    /**
     * 查询项目内对应流程
     * @author Annie
     * @time 2023/9/30 9:52
     * @param[1] houseId
     * @param[2] flowCd
     * @return List<FlowDO>
     */
    @Override
    public List<FlowDO> getFlowByHouseIdAndFlowCd(Long houseId,Integer flowCd) {

        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("house_id", houseId);
        queryWrapper.in("status_cd", FlowStatusEnum.FLOW_STATUS_ENUM_0.getCode(),FlowStatusEnum.FLOW_STATUS_ENUM_1.getCode());
        // 施工流程
        queryWrapper.eq("flow_cd", flowCd);
        return flowMapper.selectList(queryWrapper);
    }

    @Override
    public List<FlowDO> getFlowAll(Long  houseId) {
        //  SecurityFrameworkUtils  getLoginUserRoleIds 获取当前用户角色 getLoginUser  获取当前用户  getLoginUserId  用户编号
        /*1.根据用户Id 获取角色Id   2. 根据角色查询不同的流程*/
        QueryWrapper queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("house_id", houseId);
        Set<String> flowCds = new HashSet<>();
        flowCds.add(FlowCdEnum.FLOW_CD_0.getCode().toString());
        flowCds.add(FlowCdEnum.FLOW_CD_1.getCode().toString());
        flowCds.add(FlowCdEnum.FLOW_CD_2.getCode().toString());
        // 施工流程
        queryWrapper.in("flow_cd", flowCds);
        queryWrapper.eq("status_cd",FlowStatusEnum.FLOW_STATUS_ENUM_1.getCode());
        return flowMapper.selectList(queryWrapper);
    }
    @Override
   public void startFlow(Long houseId,Long flowCd){
        FlowDO flowDO = new FlowDO();
        flowDO.setStatusCd(FlowStatusEnum.FLOW_STATUS_ENUM_1.getCode());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("house_id",houseId);
        queryWrapper.eq("flow_cd",flowCd);
        queryWrapper.eq("status_cd",FlowStatusEnum.FLOW_STATUS_ENUM_0.getCode());

        flowMapper.update(flowDO,queryWrapper);
    }
    @Override
    public void startFlowAll(Long houseId){
        FlowDO flowDO = new FlowDO();
        flowDO.setStatusCd(FlowStatusEnum.FLOW_STATUS_ENUM_1.getCode());
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("house_id",houseId);
        queryWrapper.eq("status_cd",FlowStatusEnum.FLOW_STATUS_ENUM_0.getCode());

        flowMapper.update(flowDO,queryWrapper);
    }

    /**
     * @param ids
     * @return
     */
    @Override
    public List<FlowCountDO> getFlowCountList(Collection<Long> ids) {

        return flowMapper.getPurchaseFlowCountList(ids, SecurityFrameworkUtils.getLoginUserId());
    }
}
